#pragma once

#ifndef __CANVAS_REGEX_REGEXAUTOMATION_H
#define __CANVAS_REGEX_REGEXAUTOMATION_H

#include "..\Ptr.h"
#include "..\ObjectString.h"
#include "..\Collection.h"

#include "RegExData.h"

namespace Canvas
{
	namespace RegExInternal
	{
		using Collection::List;
		class State;
		class Transition 
		{
		public:
			enum class Type
			{
				Chars,
				Epsilon,
				BeginString,
				EndString,
				Nop,
				Capture,
				Match,
				Positive,
				Negative,
				NegativeFail,
				End
			};

			State* source;
			State* target;
			CharRange range;
			Type type;
			int capture;
			int index;
		};

		class State
		{
		public:
			List<Transition*> transitions;
			List<Transition*> inputs;
			bool finalState;
			void* userData;
		};

		class Automation
		{
		public:
			typedef Ptr<Automation> Ref;
			
			List<Ptr<State>> states;
			List<Ptr<Transition>> transitions;
			List<WString> captureNames;
			State* startState;

			Automation();

			State* NewState();
			Transition* NewTransition(State* start, State* end);
			Transition* NewChars(State* start, State* end, CharRange* range);
			Transition* NewEpsilon(State* start, State* end);
			Transition* NewBeginString(State* start, State* end);
			Transition* NewEndString(State* start, State* end);
			Transition* NewNop(State* start, State* end);
			Transition* NewCapture(State* start, State* end, int capture);
			Transition* NewMatch(State* start, State* end, int capture, int index = -1);
			Transition* NewPositive(State* start, State* end);
			Transition* NewNegative(State* start, State* end);
			Transition* NewNegativeFail(State* start, State* end);
			Transition* NewEnd(State* start, State* end);

		};
	}
}

#endif // !__CANVAS_REGEX_REGEXAUTOMATION_H
